3. Plotting¶
Matplotlib is a standard plotting library of python. We begin by importing it first along with numpy.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
The most widely used function in matplotlib is plot, which allows you to plot 1D and 2D data. Here is a simple example:
# Compute the x and y coordinates for points on a sine curve
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# Plot the points using matplotlib
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x7fe2dd65bd10>]
We can easily customize the style of plots for poster/talk/paper
print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
plt.style.use(['seaborn-white'])
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x7fe2dd551350>]
if we want to customize plots it is better to plot by first defining fig and ax objecs which have manuy methods for customizing figure resolution and plot related aspects respecticely.
fig, ax = plt.subplots()
y_sin = np.sin(x)
y_cos = np.cos(x)
# Plot the points using matplotlib
ax.plot(x, y_sin)
ax.plot(x, y_cos)
# Specify labels
ax.set_xlabel('x axis label')
ax.set_ylabel('y axis label')
ax.set_title('Sine and Cosine')
ax.legend(['Sine', 'Cosine'])
#fig.savefig("myfig.pdf")
<matplotlib.legend.Legend at 0x7fe2dd5155d0>
3.1. A gallery of useful examples¶
For a greater variety of plotting examples check out Matploltib Gallery!
1D plotting is conveniently done by creating fig and ax objects which allow coutom styling plots and figure properties separately.
fig, ax = plt.subplots() # Create fig and ax objects
t = np.arange(0.0, 2*np.pi, 0.1) # create x values via np.arange or np.linspace
s = np.sin(t) # create y values
ax.plot(t, s, '-o') # make the plot
#fig.savefig('myFIG.png') # save figure
[<matplotlib.lines.Line2D at 0x7fe2dd3b8e50>]
3.1.1. fig and ax objects¶
For customizing plots it is more convenient to define fig and ax objects. One can then use ax object to make veriety of subplots then use fig to save the entire figure as one pdf. Try changing fig size, number of columns and rows.
t = np.arange(0.0, 2*np.pi, 0.1) # create x values
s = np.sin(t) # create y values
fig, ax = plt.subplots(nrows=1,ncols=2,figsize=(6,3))
ax[0].plot(t, s,'-o', color='purple', lw=1.0) # plot on subplot-1
ax[1].plot(t, s**2,'-o', color='green', lw=1.0) # plot on subplot-2
#fig.savefig('sd.png') # save the figure
[<matplotlib.lines.Line2D at 0x7fe2dd30ced0>]
3.1.2. Plotting in 2D¶
To make 2D plots we need to generate 2D grid \((x,y)\) of points and pass it to our function \(f(x,y)\)
x = np.arange(0.0, 2*np.pi, 0.1) # create x values
y = np.arange(0.0, 2*np.pi, 0.1) # create y values
X, Y = np.meshgrid(x,y) # tunring 1D array into 2D grids of x and y values
Z = np.sin(X) * np.cos(Y) # feed 2D grids to our 2D function f(x,y)
fig, ax = plt.subplots() # Create fig and ax objects
ax.pcolor(X, Y, Z,cmap='RdBu') # plot
# try also ax.contour, ax.contourf
/opt/hostedtoolcache/Python/3.7.10/x64/lib/python3.7/site-packages/ipykernel_launcher.py:9: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later.
if __name__ == '__main__':
<matplotlib.collections.PolyCollection at 0x7fe2dd2a1fd0>
3.1.3. 3D plots with matplotlib¶
from matplotlib import cm, colors
from mpl_toolkits.mplot3d import Axes3D
# Create fig and ax objects for 3d plotting
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
# Using X,Y,Z grid of points in previous step
ax.plot_surface(X, Y, Z, cmap='RdYlBu')
<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7fe2dd0559d0>
3.1.4. Plotting histograms with matplotlib¶
fig, ax = plt.subplots()
# Make up some random data
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# Plot 1D histogram of the data
hist = ax.hist(x, bins=40, density=True)
fig, ax = plt.subplots()
# Make up some random data
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
y = mu + 2*sigma * np.random.randn(10000)
# Plot 2D histogram of the data
hist = ax.hist2d(x, y, bins=40, density=True, cmap='RdBu_r')
3.1.5. Plotting histograms with seaborn¶
For visualizing statistical plots there is a specialized library build on top of matplotlib that simplifies many intermediate steps that are needed to go from data to beautiful and polished visualization.
import seaborn as sns
from scipy import stats
# Make up some random data
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
sns.displot(x, kind="kde")
<seaborn.axisgrid.FacetGrid at 0x7fe2cbeddfd0>
3.2. Pandas and seaborn! a power couple for multivariate statistics visualization¶
# Normal distribution of points
n_points=200
df = pd.DataFrame({ 'X': 1*np.random.randn(n_points),
'Y': 5*np.random.randn(n_points),
'Z': 1+5*np.random.randn(n_points),
'time': np.linspace(0,n_points,n_points)
})
sns.jointplot(data=df, x='X', y='Z',
kind="kde", cmap='RdBu_r')
<seaborn.axisgrid.JointGrid at 0x7fe2cbf8e290>
3.3. Interactive plots¶
from ipywidgets import widgets
3.4. Interactiviy via Plotly-express¶
Plotly is large multi-language interactive graphing library that covers Python/Julia/R.
Plotly-dash is a framework for building web dashborads with itneractive plotly graphs.
Plotly-express is a high level library for quick visualizations whihc is similiar to seaborn vs matploltib in its philosophy
Check out this cool website built using Dash-Plotly
px.density_heatmap(df, x='X', y='Y')
#px.line(df, x='X', y='Y')
#px.scatter(df, x='X', y='Y')
#px.area(df, x='X', y='Y')
#px.histogram(df, x="X")
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-17-2f338b988a2c> in <module>
----> 1 px.density_heatmap(df, x='X', y='Y')
2 #px.line(df, x='X', y='Y')
3 #px.scatter(df, x='X', y='Y')
4 #px.area(df, x='X', y='Y')
5 #px.histogram(df, x="X")
NameError: name 'px' is not defined
fig = px.scatter(df, x="X", y="Y", size=20*np.ones(n_points),
animation_frame="time", animation_group='Y', color='Y',
range_x=[-20,20], range_y=[-20,20]
)
fig.show()
3.4.1. Too many libraries for visualization in pyviz universe? Enter Holoviews!¶
We all can agree there are just too many options for visualizing data and sometimes it is impossible to pick one and stick with becaue different libaries have different strengths when it comes visualizing different kinds of data. Plotly does a gread job with 3D visualization while matploltib is mostly desinged for 2D plots. Seaborn has everying one needs to genreate statistical plots while plotly may cover ony a subgroup of seaborn, etc. One emerging idea in scientific software desing is to create library agnostic tools. E.g if you want to plot histogram you can do it either using several different libraries or using a library agnsotic tool by specifiying the particular library interface for the visualization.
Holoviews A library agnostic tool living in python universe for high level visualizations.
“Stop plotting your data - annotate your data and let it visualize itself”
# May have to run this in GoogleCollab to show the plots
#!pip install -q holoviews
import holoviews as hv
hv.extension('plotly') # try 'bokeh' or 'matplotlib'
data = [1,2,4,8,16,25]
#hv.Curve(data) + hv.Scatter(data) # adding crates subplots
hv.Curve(data) * hv.Scatter(data) # multiplying creates overlay
data = df[['X', 'Y']].values
#hv.Curve(data)
hv.Scatter(data) + hv.Curve(data) + hv.Points(data) + hv.Bivariate(data)
#hv.Histogram(df['X'], density=True, bins=50)
#Example of 3D plot
hv.extension('plotly') # try 'bokeh' or 'matplotlib'
Z = np.sin( np.random.randn(40,40) )**5
hv.Surface(Z, bounds=(-5, -5, 5, 5))
3.4.2. Using interactive widgets¶
Suppose we would like to explore how the variation of parameter \(\lambda\) affects the following function of a standing wave:
Make a python-function which creates a plot as a function of a parameter(s) of interest.
Add an interactive widget on top to vary the parameter.
from ipywidgets import interact
@widgets.interact(phase=(0,2*np.pi), freq = (0.1,5))
def wave(phase=0, freq=0.5):
x = np.linspace(0,10,1000)
y = np.sin(freq*x+phase)
plt.plot(x, y)
def wave(phase, freq):
x = np.linspace(0,10,1000)
y = np.sin(freq*x+phase)
return hv.Curve((x, y))
## Option-1: make dictionary of data points and pass to HoloMap
hv.HoloMap({(p,freq):wave(p,freq) for freq in np.linspace(0.1,5,10) for p in np.linspace(0, 2*np.pi,10)}, kdims=['phase', 'frequency'])
## Option-2: Define ranges of variables and pass to DynamicMap
#hv.DynamicMap(wave, kdims=['p', 'freq']).redim.range(p=(0.1,2*np.pi), freq=(0.1,5))
hv.HoloMap(data, kdims=['phase', 'frequency'])
3.5. Additional resoruces.¶
Matplotlib has a huge scientific user base. This means that you can always find a good working template of any kind of visualization which you want to make. With basic understanding of matplotlib and some solid googling skills you can go very far. Here are some additional resources that you may find helpful